#include "device.h"
#include "component.h"
#include "motor_bigpro.h"

/* 调试打印接口 */
#define LOCKBIGPRO_LOG(format, ...)  OSAL_LOG("[lockbigpro.c] " C_PURPLE format C_NONE, ##__VA_ARGS__)


/* 电机电流采集的ADC通道 */
#define LOCKBIG_DCI_ADC_CHANNEL					vADC_1
/* 计数器 */
#define IRQ_VHW_LOCKBIG_COUNTER					vCOUNTER_0

/* 事件 */
#define EVENT_MOTOR_MONITOR                     (0X00000001)  //电机监控事件

/* 电机控制参数 */
#ifndef MOTOR_PARAM_DCI_OVERFLOW_SMALL
#define MOTOR_PARAM_DCI_OVERFLOW_SMALL          800    //小扭力堵转电流1000mA
#endif
#define MOTOR_PARAM_DCI_OVERFLOW_LARGE          3500    //大扭力堵转电流3500mA

#define MOTOR_PARAM_MAX_REPEAT_TIMES            3       //最大重复次数（上锁/开锁失败后，会自动重复3次）
#define MOTOR_PARAM_STOP_TIME1                  1000    //电机暂停时间1（电机运行正常运行过程中状态切换需要的暂停时间）
#define MOTOR_PARAM_STOP_TIME2                  2000     //电机暂停时间2（开锁堵转暂停时间、电机运行流程结束最后的暂停时间）
#define MOTOR_PARAM_TURN_TIMEOUT                8000    //电机正常运行，超时时间
#define MOTOR_PARAM_LOCK_BACK_TIMEOUT           300     //上锁电机回拖运行，超时时间
#define MOTOR_PARAM_BACK_TIMEOUT                2000     //开锁电机回拖运行，超时时间
#define MOTOR_PARAM_DCI_DETECT_DELAY_TIME       200      //电机启动后，电流检测延迟时间
#define MOTOR_PARAM_BRAKE_TIME                  100      //电机刹车时间,给结构齿轮自动回拖时间

/* 电机监测时间间隔 */
#define MOTOR_MONITOR_TIME                      (10)    //电机监测时间间隔 10ms
/* 电机上锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_LOCKED_TIME               (1000)
/* 电机开锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_UNLOCK_TIME               (100)  

/*上锁回拖计数器阈值*/
#define MOTOR_LOCKED_BACK_COUNTER				(160)

/*开锁回拖计数器阈值*/
#define MOTOR_UNLOCK_BACK_COUNTER				(15)

#define LOCK_CNT_DEVIATION_VALUE				15	//上锁编码器偏差值
#define UNLOCK_CNT_DEVIATION_VALUE				2	//开锁编码器偏差值
#define MANUAL_LOCK_CNT_DEVIATION_VALUE			90	//机械上锁编码器偏差值
#define MANUAL_UNLOCK_CNT_DEVIATION_VALUE		80	//机械开锁编码器偏差值


/* 锁体状态 */
static enum
{
	LOCK_STA_UNKNOW,    		//未知状态
	LOCK_STA_LOCKING,   		//正在上锁
	LOCK_STA_UNLOCKING, 		//正在开锁
	LOCK_STA_UNLOCKING_BACK, 	//正在开锁回拖
	LOCK_STA_LOCKING_BACK, 		//正在上锁回拖
	LOCK_STA_LOCKED,    		//已上锁
	LOCK_STA_UNLOCK,    		//已开锁
}lockStatus = LOCK_STA_UNKNOW;

/* 电机状态类型 */
typedef enum
{
	MOTOR_STA_LOCKED,               //电机状态：正在上锁
	MOTOR_STA_LOCKED_BRAKE,         //电机状态：上锁刹车
	MOTOR_STA_UNLOCK,               //电机状态：正在开锁
	MOTOR_STA_UNLOCK_BRAKE,         //电机状态：开锁刹车
	MOTOR_STA_UNLOCK_BACK,          //电机状态：正在开锁回拖
	MOTOR_STA_BACK,					
    MOTOR_STA_STOP,                 //电机状态：已停止
	MOTOR_STA_IDLE,                 //电机空闲
}MotorStatus_enum_t;

/* 电机状态数据 */
static struct
{
	volatile MotorStatus_enum_t last;    	//电机上一次的活动状态  只能是：MOTOR_STA_LOCKED  MOTOR_STA_UNLOCK
	volatile MotorStatus_enum_t current; //电机当前状态	
	volatile uint32_t startTime;         //电机当前状态开始时间
	volatile uint32_t timeout;           //电机当前状态超时时间
}motorStatus = {MOTOR_STA_IDLE, MOTOR_STA_IDLE};


/* 电机运行错误情况 */
volatile static enum
{
	ERR_NO_ERROR,       //无错误
	ERR_LOCK_ERROR,     //锁体错误（电机运转结束时，传感器状态不对）
	
	ERR_LOCKED_TIMEOUT, //上锁超时
	ERR_UNLOCK_TIMEOUT, //开锁超时
	ERR_BACK_TIMEOUT,   //回拖超时
	
	ERR_LOCKED_DCI,     //上锁过流
	ERR_UNLOCK_DCI,     //开锁过流
	ERR_BACK_DCI,       //回拖过流
}motorError = ERR_NO_ERROR;

/* 电机刹车原因类型 */
typedef enum
{
	MOTOR_BRAKE_NO_SOURCE,              //无刹车源
    MOTOR_BRAKE_LOCKED,                 //上锁刹车
    MOTOR_BRAKE_UNLOCK,                 //开锁刹车
}MotorBrakeSource_enum_t;

/* 上锁方向类型 */
typedef enum
{
	LOCKED_DIR_UNKNOWN,                 //未知上锁方向
    LOCKED_DIR_CW,                      //顺时针上锁方向
    LOCKED_DIR_CCW,                     //逆时针上锁方向
}Locked_Dir_enum_t;

/* 锁体控制阶段类型 */
typedef enum
{
	LOCK_CTRL_STEP_INIT,				//初始状态
	LOCK_CTRL_STEP_LOCK,				//上锁阶段
	LOCK_CTRL_STEP_UNLOCK,				//开锁阶段
    LOCK_CTRL_STEP_BLOCK,				//堵转阶段
    LOCK_CTRL_STEP_BACK,                //回拖阶段

}Lock_Ctrl_Step_enum_t;

/* 锁体模式 */
typedef enum
{
    LOCKED_MODE_NORMAL,                 //普通模式
    LOCKED_MODE_TEST,                   //测试模式
}Locked_Mode_enum_t;


/* 中断挂起标志 */
volatile static uint8_t isrPendFlag;        //中断挂起标志

/* 锁体模式 */
__attribute__((unused))  static Locked_Mode_enum_t lockedMode = LOCKED_MODE_NORMAL;

/* 上锁阶段 */
static Lock_Ctrl_Step_enum_t lockedCtrlStep = LOCK_CTRL_STEP_INIT;

/* 电机配置参数 */
static struct
{
	uint16_t range_sum;		//电机总行程
    uint8_t init_flag; //初始化标志
    uint8_t torque;    //电机扭力（1：大扭力、0：小扭力）
    uint8_t dir;       //电机方向（1：锁在门的右侧、0：锁在门的左侧）
}lock_config;


static struct 
{
	uint16_t range_sum;			//编码器总行程
	uint16_t tem_range_max;		//编码器临时行程最大值
	uint16_t tem_range_min;		//编码器临时行程最小值
	uint16_t range_max;			//编码器行程最大值
	uint16_t range_min;			//编码器行程最小值
	uint32_t encoder_cnt;		//编码器计数值	
}encoder_data = {0,0,0,0,0,0};

static uint8_t motor_reset_init_flag;	//电机重启校准标志位
static uint8_t motor_calibrate_flag = 0;	//	
static uint8_t lock_mute = 0;		

static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl);
static ErrorStatus LockBigPro_Unlock(void);
static ErrorStatus LockBigPro_Unlock_Back(void);



/**
  * @brief  电机校准
  *         
  * @note   锁第一次使用获取初始校准值
  */
static void LockBigPro_MotorCalibrate(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: //上锁

			if(lock_config.dir == LOCKED_DIR_LEFT)
			{
				encoder_data.range_max = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock range max :%d\r\n",encoder_data.range_max);
			}
			else
			{
				encoder_data.range_min = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock range min :%d\r\n",encoder_data.range_min);

			}
			break;

		case MOTOR_STA_UNLOCK: //开锁

			if(lock_config.dir == LOCKED_DIR_LEFT)
			{
				encoder_data.range_min = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock range min :%d\r\n",encoder_data.range_min);
				
			}
			else
			{
				encoder_data.range_max = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock range max :%d\r\n",encoder_data.range_max);

			}

			break;

		default: 
            return;
	}

	//已校准
	if((encoder_data.range_max != 0) && (encoder_data.range_min != 0))
	{
		encoder_data.range_sum = abs(encoder_data.range_max - encoder_data.range_min);
		lock_config.range_sum = encoder_data.range_sum;
		lock_config.init_flag = 0xFA;
		motor_reset_init_flag = 1;
		OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
		lockMsg.lock = LOCK_ACTION_CALIBRATE;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
		LOCKBIGPRO_LOG("lock range sum :%d, dir:%d\r\n",encoder_data.range_sum,lock_config.dir);
		motor_calibrate_flag = 0;
		
	}

}

/**
  * @brief  电机重启校准
  *         
  * @note   锁断电重启后需要重新获取校准值最大值和最小值
  */
static void LockBigPro_MotorResetCalibrate(void)
{
	uint16_t tem_range_sum;
	uint16_t range_dif;
	static uint8_t calibrate_flag = 0; 
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: //上锁

			if(lock_config.dir == LOCKED_DIR_LEFT)
			{
				encoder_data.tem_range_max = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock tem range max :%d\r\n",encoder_data.tem_range_max);
			}
			else
			{
				encoder_data.tem_range_min = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock tem range min :%d\r\n",encoder_data.tem_range_min);
			}
			lockMsg.lock = LOCK_ACTION_LOCKED;
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报

			break;

		case MOTOR_STA_UNLOCK: //开锁

			if(lock_config.dir == LOCKED_DIR_LEFT)
			{
				encoder_data.tem_range_min = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock tem range min :%d\r\n",encoder_data.tem_range_min);
			}
			else
			{
				encoder_data.tem_range_max = encoder_data.encoder_cnt;
				LOCKBIGPRO_LOG("lock tem range max :%d\r\n",encoder_data.tem_range_max);
			}
			lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报

			break;

        case MOTOR_STA_UNLOCK_BACK: 

            break;

		default: 
            return;
	}

	if((encoder_data.tem_range_max != 0) && (encoder_data.tem_range_min != 0))
	{
		//临时总行程
		tem_range_sum = abs(encoder_data.tem_range_max - encoder_data.tem_range_min);
		LOCKBIGPRO_LOG("tem_range_sum %d\r\n",tem_range_sum);

		//临时的总行程和上次保存的总行程差在5范围内，则为正常
		range_dif = abs(tem_range_sum - lock_config.range_sum);
		if(range_dif <= 5)		
		{
			encoder_data.range_max = encoder_data.tem_range_max;
			encoder_data.range_min = encoder_data.tem_range_min;
			motor_reset_init_flag = 1;
			LOCKBIGPRO_LOG("LockBigPro motor reset Calibrate success ,max:%d, min:%d \r\n",encoder_data.range_max,encoder_data.range_min);
			//LockBigPro_Unlock_Back();
		}
		else
		{
			//重校准的行程大于初始校准行程
			if(tem_range_sum > lock_config.range_sum)
			{
				//电机异常
				LOCKBIGPRO_LOG("LockBigPro motor abnormal , current range > last range\r\n");
				lockMsg.lock = LOCK_ACTION_CALIBRATE_ERROR;
				OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
			}
			else
			{
				LOCKBIGPRO_LOG("LockBigPro motor reset Calibrate error\r\n");
			}

		}
	} 
			
}

/**
  * @brief  电机保护
  * @note   
  *
  */
static ErrorStatus LockBigPro_LockProtect(LockCtrl_enum_t ctrl)
{
	if(ctrl == LOCK_CTRL_LOCKED)
	{
		if((encoder_data.range_max != 0) && (encoder_data.range_min != 0))
		{
			if(lock_config.dir == LOCKED_DIR_LEFT)
			{
				if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE)
				{
					return ERROR;
				}
			}
			else
			{
				if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE )
				{
					return ERROR;
				}
			}
		}


	}

	return SUCCESS;
}


/**
  * @brief  切换电机状态
  * @note   
  *
  * @param  status：需要切换的状态
  * @param  timeout：该状态的超时时间
  */
static void LockBigPro_SwitchMotorStatus(MotorStatus_enum_t status, uint32_t timeout)
{

	if (MOTOR_STA_LOCKED == motorStatus.current ||  MOTOR_STA_UNLOCK == motorStatus.current)
	{
		/* 保存电机上次的活动状态 */
		motorStatus.last = motorStatus.current;
	}

	motorStatus.current = status;			//电机当前状态
	motorStatus.timeout = timeout;			//电机操作超时时间
	motorStatus.startTime = OSAL_GetTickCount();
	LOCKBIGPRO_LOG("start time %d , %d\r\n",motorStatus.startTime,motorStatus.current);
    if (MOTOR_STA_BACK == motorStatus.current)
	{
		if (MOTOR_STA_LOCKED == motorStatus.last)
		{
			/* 上锁回拖 */
			MotorBigPro_TurnRight();//上锁回拖操作跟开锁操作控制电机的方向是一致的
		}
		else if (MOTOR_STA_UNLOCK == motorStatus.last || MOTOR_STA_IDLE == motorStatus.last)
		{
			/* 开锁回拖 */
			MotorBigPro_TurnLeft();//开锁回拖操作跟上锁操作控制电机的方向是一致的
		}

    }
	else if(MOTOR_STA_UNLOCK_BACK == motorStatus.current)
	{
		/* 开锁回拖 */
		MotorBigPro_TurnLeft();//开锁回拖操作跟上锁操作控制电机的方向是一致的		
	}
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BRAKE == motorStatus.current )
	{
		/* 刹车 */
		MotorBigPro_Brake();
	}
	else if (MOTOR_STA_LOCKED == motorStatus.current)
	{
		/* 电机上锁 */
		MotorBigPro_TurnLeft();
	}
	else if (MOTOR_STA_UNLOCK == motorStatus.current)
	{
		/* 电机开锁 */
		MotorBigPro_TurnRight();
	}
	else
	{
		/* 电机停止 */
		MotorBigPro_Stop();
	}
}

/**
  * @brief  处理上锁流程结束
  *         
  * @note   
  */
static void LockBigPro_MotorLockedEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));

	lock_mute = 1;
	LOCKBIGPRO_LOG("LockBigPro_MotorLockedEnd\r\n");
	if(lockedCtrlStep == LOCK_CTRL_STEP_BLOCK || lockedCtrlStep == LOCK_CTRL_STEP_LOCK)
	{

		motorError = ERR_NO_ERROR;
		lockedCtrlStep = LOCK_CTRL_STEP_BACK;		//标记为回拖阶段
		lockStatus = LOCK_STA_LOCKING_BACK;

		LockBigPro_SwitchMotorStatus(MOTOR_STA_BACK, MOTOR_PARAM_LOCK_BACK_TIMEOUT);
		return;
	}


	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
	
	if(motorError == ERR_LOCKED_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-上锁超时,上锁回拖超时
	}
	else
	{
		lockMsg.lock = LOCK_ACTION_LOCKED;//上锁成功
	}
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁流程结束
  *         
  * @note   
  */
static void LockBigPro_MotorUnlockEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));

	lock_mute = 2;
	LOCKBIGPRO_LOG("LockBigPro_MotorUnlockEnd %d\r\n",lockedCtrlStep);
/*
	if(lockedCtrlStep == LOCK_CTRL_STEP_BLOCK || lockedCtrlStep == LOCK_CTRL_STEP_UNLOCK)
	{

		motorError = ERR_NO_ERROR;
		lockedCtrlStep = LOCK_CTRL_STEP_BACK;		//标记为回拖阶段
		lockStatus = LOCK_STA_UNLOCKING_BACK;

		LockBigPro_SwitchMotorStatus(MOTOR_STA_BACK, MOTOR_PARAM_BACK_TIMEOUT);
		return;
	}
*/
	if(motorError == ERR_UNLOCK_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-开锁超时
	}
	else
	{
		lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;//开锁成功,未回拖
	}

	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁回拖流程结束
  *         
  * @note   
  */
static void LockBigPro_MotorUnlockBackEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPRO_LOG("LockBigPro_MotorUnlockBackEnd\r\n");

	lockMsg.lock = LOCK_ACTION_UNLOCK_BACK;//开锁成功,已回拖
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理上锁回拖流程结束
  *         
  * @note   
  */
static void LockBigPro_MotorLockBackEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPRO_LOG("LockBigPro_MotorUnlockBackEnd\r\n");

	lockMsg.lock = LOCK_ACTION_LOCKED;//上锁成功,已回拖
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}


static void LockBigPro_MotorAbnormalEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPRO_LOG("timeout error, motorError:%d\r\n", motorError);

	lockMsg.lock = LOCK_ACTION_ABNORMAL;			//
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));	//消息上报
	
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
	motorError = ERR_NO_ERROR; 
	motorStatus.current = MOTOR_STA_IDLE;
}

/**
  * @brief  电机运行结束处理
  *         
  * @note   
  */
static void LockBigPro_MotorTurnEnd(void)
{
	LOCKBIGPRO_LOG("init_flag %02x,lockStatus:%d,motorError:%d\r\n",lock_config.init_flag,lockStatus,motorError);
	if(lock_config.init_flag != 0xFA && (motor_calibrate_flag))	//未校准
	{
		//电机未校准 上锁完自动开锁
		if(lockStatus ==  LOCK_STA_LOCKING && (motorError != ERR_LOCKED_TIMEOUT))
		{
			LockBigPro_Unlock();	//
		}


		if((motorError == ERR_UNLOCK_TIMEOUT) || (motorError == ERR_LOCKED_TIMEOUT) || (motorError == ERR_BACK_TIMEOUT) || (motorError == ERR_BACK_DCI))
		{
			
			LockBigPro_MotorAbnormalEnd();
			motor_calibrate_flag = 0;
		}
		

	}
	else
	{

		if(motorError == ERR_BACK_TIMEOUT)
		{
			if(lockStatus == LOCK_STA_UNLOCKING_BACK)
			{
				/* 处理开锁回拖流程结束 */
				LockBigPro_MotorUnlockBackEnd();
			}
			else
			{
				/* 处理上锁回拖流程结束 */
				LockBigPro_MotorLockBackEnd();
			}
		}
		else if(motorError == ERR_LOCKED_DCI || motorError == ERR_UNLOCK_DCI || motorError == ERR_BACK_DCI)	//过流
		{
			OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
			motorError = ERR_NO_ERROR; 
			motorStatus.current = MOTOR_STA_IDLE;

		}
		else if(motorError == ERR_LOCKED_TIMEOUT || motorError == ERR_UNLOCK_TIMEOUT)	//超时
		{
			LockBigPro_MotorAbnormalEnd();
		}
		else if (lockStatus == LOCK_STA_LOCKING)
		{
			/* 处理上锁流程结束 */
			LockBigPro_MotorLockedEnd();
		}
		else if (lockStatus == LOCK_STA_UNLOCKING)
		{
			/* 处理开锁流程结束 */
			LockBigPro_MotorUnlockEnd();
		}
		else if (lockStatus == LOCK_STA_UNLOCKING_BACK)
		{
			/* 处理开锁回拖流程结束 */
			LockBigPro_MotorUnlockBackEnd();
		}

	}
    
}

/**
  * @brief  电机运行超时
  *         
  * @note   
  */
static void LockBigPro_MotorTimeout(void)
{

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED:      //上锁超时
            motorError = ERR_LOCKED_TIMEOUT; 
            break;
		case MOTOR_STA_UNLOCK:      //开锁超时  
            motorError = ERR_UNLOCK_TIMEOUT; 
            break;
        case MOTOR_STA_BACK: //开锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
		default: 
            break;
	}

	LOCKBIGPRO_LOG("lock timeout motorStatus:%d\r\n",motorStatus.current);
    if (MOTOR_STA_STOP == motorStatus.current)	/* 电机STOP 超时 */     
	{
        LockBigPro_MotorTurnEnd();
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current)		/* 上锁刹车超时*/
	{	
		LockBigPro_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
	}
	else if (MOTOR_STA_UNLOCK_BRAKE == motorStatus.current)		/* 开锁刹车超时*/
	{

		LockBigPro_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);

	}
    else
    {
		/* 上锁超时、开锁超时、回拖超时、*/
        LockBigPro_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
    }
}


/**
  * @brief  电机量程检查
  * @note   当已经校准过，但又触发了堵转，检查编码器当前是否到达指定值（可能存在开关锁到位了，但编码器没有触发）
  *
  */
static ErrorStatus LockBigPro_RangeCheck(void)
{
	LOCKBIGPRO_LOG("LockBigPro_RangeCheck: \r\n");
	if(motorStatus.current == MOTOR_STA_UNLOCK)
	{
		if(lock_config.dir == LOCKED_DIR_LEFT)
		{
			if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= (UNLOCK_CNT_DEVIATION_VALUE + 6))
			{
				LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
				LOCKBIGPRO_LOG("check encode unlock in place %d\r\n",encoder_data.encoder_cnt);
				return SUCCESS;
			}
		}
		else
		{
			if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= (UNLOCK_CNT_DEVIATION_VALUE + 6))
			{
				LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
				LOCKBIGPRO_LOG("check encode unlock in place %d\r\n",encoder_data.encoder_cnt);
				return SUCCESS;
			}
		}
	}
	else if(motorStatus.current == MOTOR_STA_LOCKED)
	{
		if(lock_config.dir == LOCKED_DIR_LEFT)
		{
			if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE)
			{
				LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
				LOCKBIGPRO_LOG("check encode lock in place %d\r\n",encoder_data.encoder_cnt);
				return SUCCESS;
			}
		}
		else
		{
			if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE )
			{
				LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
				LOCKBIGPRO_LOG("check encode lock in place %d\r\n",encoder_data.encoder_cnt);
				return SUCCESS;
			}
		}
	}

	return ERROR;

}


/**
  * @brief  检查电机电流
  *         
  * @note   只有以下三种电机状态，才需要检查电流：
  *         MOTOR_STA_LOCKED：上锁状态
  *         MOTOR_STA_UNLOCK：开锁状态
  *         MOTOR_STA_BACK：回拖状态
  */
static void LockBigPro_MotorCheckDCI(void)
{
	uint16_t dci, dci_overflow;		//dci_overflow 过流值
	uint8_t overflowCnt = 0;

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: 
		case MOTOR_STA_UNLOCK: 
        case MOTOR_STA_BACK: 
            break;
		default: 
            return;
	}

	//根据扭力选择过流值
    dci_overflow = (lock_config.torque == LOCKED_TORQUE_HIGH) ? MOTOR_PARAM_DCI_OVERFLOW_LARGE : MOTOR_PARAM_DCI_OVERFLOW_SMALL;

    do /* 有过流时：就连续获取10次电流 */
    {
        dci = (uint16_t)Device_Read(LOCKBIG_DCI_ADC_CHANNEL, NULL, 0, 0);
        dci *= 2; //mV转换成mA（电机驱动串的电阻是0.5Ω）
        overflowCnt++;
    }while (dci >= dci_overflow && overflowCnt < 10);


	if(dci > dci_overflow)
	{
		LOCKBIGPRO_LOG("dci:%d   dci_overflow:%d\r\n", dci, dci_overflow);
		LOCKBIGPRO_LOG("cur encoder cnt:%d\r\n",encoder_data.encoder_cnt);
	}
	else
	{
		//LOCKBIGPRO_LOG("dci:%d   dci_overflow:%d\r\n", dci, dci_overflow);
	}


    if (overflowCnt >= 10)
    {
		LockMsg_t lockMsg;
		memset(&lockMsg, 0, sizeof(lockMsg));

		if(lock_config.init_flag != 0xFA && (motor_calibrate_flag))	//未校准
		{
			LockBigPro_MotorCalibrate();
		}
		else
		{
			if(motor_reset_init_flag == 0)	//锁重启 电机需要重新校准
			{
				LockBigPro_MotorResetCalibrate();
				// if(motor_reset_init_flag)
				// {
				// 	return;
				// }

			}
			else
			{

				if(LockBigPro_RangeCheck())
				{
					return ;
				}
				else
				{
					motorError = ERR_LOCKED_DCI; 
					lockMsg.lock = LOCK_ACTION_DCI_ERROR;
					OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
				}

				
			}
		}

        /* 连续10次过流：标记错误情况，电机进入STOP状态 */
        if (motorStatus.current == MOTOR_STA_LOCKED)//上锁过流
        {
            motorError = ERR_LOCKED_DCI; 
            lockedCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_STOP_TIME1);//上锁过流停机
        }
        else if (motorStatus.current == MOTOR_STA_UNLOCK)//开锁过流
        {
			motorError = ERR_UNLOCK_DCI;
			lockedCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_STOP_TIME1);//开锁过流停机
        }
        else if (motorStatus.current == MOTOR_STA_BACK)//开锁回拖过流
        {
            motorError = ERR_BACK_DCI; 
            LockBigPro_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);//回拖过流停止
        }
		else
        {
            LockBigPro_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
        }
	}




}


/**
  * @brief  电机运行状态监控（电机监控事件）
  *         
  * @note   监控电机电流、超时
  *         电机状态不等于MOTOR_STA_IDLE时：该函数每间隔10ms运行一次
  */
static void LockBigPro_MotorMonitor(void)
{
    const uint32_t xTicks = OSAL_GetTickCount();
    uint32_t pastTime;
    pastTime = OSAL_PastTime(xTicks, motorStatus.startTime);    
	if (pastTime >= motorStatus.timeout)
	{
		LockBigPro_MotorTimeout();    /* 处理电机当前状态超时 */
	}
	else if (pastTime >= MOTOR_PARAM_DCI_DETECT_DELAY_TIME)
	{
		LockBigPro_MotorCheckDCI();   /* 检查电机运行电流（DCI） */
	}
}

/**
  * @brief  上锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPro_Locked(void)
{
	lockStatus = LOCK_STA_LOCKING;
	lockedCtrlStep = LOCK_CTRL_STEP_LOCK;
	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
	return SUCCESS;
}

/**
  * @brief  开锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPro_Unlock(void)
{
	lockStatus = LOCK_STA_UNLOCKING;
	lockedCtrlStep = LOCK_CTRL_STEP_UNLOCK;
	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
	return SUCCESS;
}

/**
  * @brief  开锁回拖接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPro_Unlock_Back(void)
{	
	lockStatus = LOCK_STA_UNLOCKING_BACK;
	lockedCtrlStep = LOCK_CTRL_STEP_BACK;
	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_BACK_TIMEOUT);
	return SUCCESS;
}

/* Lock组件API函数类型 */
static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl)
{
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    lockedMode = LOCKED_MODE_NORMAL;//标记为正常模式
    LOCKBIGPRO_LOG("Lock_Ctrl, ctrl = %d\r\n", ctrl);

    if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下报锁体繁忙,不能执行锁体操作
    {
        lockMsg.lock = LOCK_ACTION_BUSY;
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        LOCKBIGPRO_LOG("LOCK_ACTION_BUSY\r\n");
        return ERROR;
    }

    /* 变量置位 */
	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
//	unlockCtrlStep = LOCK_CTRL_STEP_INIT;
/*
	if(LockBigPro_LockProtect(ctrl) != SUCCESS)
	{
		return ERROR;
	}
	*/
	
    switch((uint8_t)ctrl)
    {
        case LOCK_CTRL_LOCKED:	
			LockBigPro_Locked();
            break;
        case LOCK_CTRL_UNLOCK:
			LockBigPro_Unlock();
            break; 
		case LOCK_CTRL_UNLOCK_BACK:
			LockBigPro_Unlock_Back();
            break; 
        default:
            break;
    }
    return SUCCESS;
}

/* 设置上锁方向的接口 */
static ErrorStatus LockBigPro_SetDir_Sub(LockedDir_enum_t ctrl)
{
	LockMsg_t lockMsg;
	LOCKBIGPRO_LOG("LockBig_SetDir: %d\r\n", ctrl);
	MotorBigPro_SetDirection((uint8_t)ctrl);
	lock_config.dir = (uint8_t)ctrl;
    OSAL_NvWrite(0, &lock_config, sizeof(lock_config));

    memset(&lockMsg, 0, sizeof(lockMsg));
    if(ctrl == LOCKED_DIR_RIGHT)
    {
        lockMsg.lock = LOCK_ACTION_DIR_RIGHT;
    }
    else
    {
        lockMsg.lock = LOCK_ACTION_DIR_LEFT;
    }
    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

	return SUCCESS;
}

/* 设置电机扭力的接口 */
static ErrorStatus LockBigPro_SetTorque_Sub(LockedTorque_enum_t torque)
{
	LOCKBIGPRO_LOG("LockBig_SetTorque: %d\r\n", torque);
	lock_config.torque = (uint8_t)torque;
	OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
	return SUCCESS;
}


static uint16_t LockBigPro_HallTest(void)
{
	uint16_t startCount, endCount;
	uint16_t sum;
	LockMsg_t lockMsg;
	startCount = (uint16_t)Device_Read(vCOUNTER_0,NULL,0,NULL);
	MotorBigPro_TurnLeft();
	
	for(uint8_t i = 0; i < 10; i++)
	{
		OSAL_DelayUs(60000);
	}
	
	endCount = (uint16_t)Device_Read(vCOUNTER_0,NULL,0,NULL);
	MotorBigPro_Stop();
	sum = abs(endCount - startCount);
	if(sum > 0)
	{
		lockMsg.sensorTestStatus = 0X0A;//高速霍尔传感器检测成功
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));	//消息上报
	}
	printf("startCount : %d, endCount : %d\r\n", startCount, endCount);

	
	
	return sum;
}


/**
  * @brief  产测模式操作上锁/开锁的接口
  * @note   
  *         
  * @param  testMode：测试模式, LOCK_UNLOCK_TEST_MODE:上锁/开锁测试 MOTOR_TEST_MODE:电机测试
  * @param  data：控制参数
  * @param  dataLen:控制参数的个数
  */
static uint16_t Lock_TestCtrl_Sub(Lock_Test_Mode_enum_t testMode, uint8_t data[], uint8_t dataLen)
{
	lockedMode = LOCKED_MODE_TEST;          //标记为测试模式
	if(testMode == LOCK_UNLOCK_TEST_MODE)	//上锁/开锁测试
    {
		return 0;
	}
	else if(testMode == MOTOR_TEST_MODE)	//电机测试
    {
		if(dataLen < 1)						//电机控制至少要有一个参数
        {
            return 0;
        }
        uint8_t motorCtrl = data[0];
		switch (motorCtrl)
		{
			case 1:
				MotorBigPro_TurnLeft();
				break;
			case 2:
				MotorBigPro_TurnRight();
				break;
			case 3:
				MotorBigPro_Stop();
				break;
			default:
				break;
		}
		return 0;
	}
	else if(testMode == HALL_TEST_MODE)	//计数霍尔测试模式
    {
		return LockBigPro_HallTest();
	}
	else
	{
		return 0;
	}
}


/**
  * @brief  计数器硬件中断
  * @note   
  * @return 
  */
static void LockBig_Counter_Irq_Handler(VirtualHardware_enum_t dev,void *data, uint32_t len)
{
	uint32_t cnt = (uint32_t *)data;
	//co_delay_us(500);
	//printf("lock encoder_data.encoder_cnt %d\r\n",cnt);
	encoder_data.encoder_cnt = cnt + 10000;
	if(encoder_data.encoder_cnt > 60000)		//兼容无法设置初值的mcu
	{
		encoder_data.encoder_cnt = encoder_data.encoder_cnt - 0xffff;
		//printf("lock encoder_data.encoder_cnt %d\r\n",encoder_data.encoder_cnt);
	}
	//printf("lock encoder_data.encoder_cnt %d\r\n",encoder_data.encoder_cnt);
	/* 创建ISR事件 */
	OSAL_EventCreateFromISR(COMP_LOCK);
}

/**
  * @brief  计数器中断处理
  * @note   
  * @return 
  */
static void LockBigPro_CounterIsr(void)
{
	uint16_t tem;
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));

	//当已知行程总行程
	if((encoder_data.range_sum != 0))
	{
		switch (motorStatus.current)
		{
			case MOTOR_STA_LOCKED: //上锁

				if(lock_config.dir == LOCKED_DIR_LEFT)
				{
					if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE)
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode lock in place %d\r\n",encoder_data.encoder_cnt);
					}
				}
				else
				{
					if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= LOCK_CNT_DEVIATION_VALUE )
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode lock in place %d\r\n",encoder_data.encoder_cnt);
					}
				}

				break;

			case MOTOR_STA_UNLOCK: //开锁

				if(lock_config.dir == LOCKED_DIR_LEFT)
				{
					if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= UNLOCK_CNT_DEVIATION_VALUE)
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode unlock in place %d\r\n",encoder_data.encoder_cnt);
					}
				}
				else
				{
					if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= UNLOCK_CNT_DEVIATION_VALUE)
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode unlock in place %d\r\n",encoder_data.encoder_cnt);
					}
				}

				break;

			case MOTOR_STA_UNLOCK_BACK: 	//开锁回拖
				if(lock_config.dir == LOCKED_DIR_LEFT)
				{
					if(abs(encoder_data.range_min - encoder_data.encoder_cnt) >= MOTOR_UNLOCK_BACK_COUNTER)
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode unlock back in place %d\r\n",encoder_data.encoder_cnt);
					}
				}
				else
				{
					if(abs(encoder_data.range_max - encoder_data.encoder_cnt) >= MOTOR_UNLOCK_BACK_COUNTER)
					{
						LockBigPro_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
						LOCKBIGPRO_LOG("encode unlock back in place %d\r\n",encoder_data.encoder_cnt);
					}
				}

				break;
				

			case MOTOR_STA_IDLE:

				if(motor_reset_init_flag == 0)
				{
					//LOCKBIGPRO_LOG("motor idle encoder %d\r\n",encoder_data.encoder_cnt);
					tem = encoder_data.range_sum - (encoder_data.tem_range_max - encoder_data.encoder_cnt);
					if((tem >= 0) && (tem <= 5) )
					{
						encoder_data.range_max = encoder_data.tem_range_max;
						encoder_data.range_min = encoder_data.tem_range_max - encoder_data.range_sum;
						motor_reset_init_flag = 1;
						LOCKBIGPRO_LOG("LockBigPro motor reset Calibrate success ,max:%d, min:%d \r\n",encoder_data.range_max,encoder_data.range_min);

					}
				}

				if(lock_config.dir == LOCKED_DIR_LEFT)
				{
					if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= MANUAL_LOCK_CNT_DEVIATION_VALUE && (lock_mute!=1))
					{
						//手动上锁
						lock_mute = 1;
						lockMsg.lock = LOCK_ACTION_LOCKED_MACH;		//机械上锁成功
						OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
						LOCKBIGPRO_LOG("manual lock in place %d\r\n",encoder_data.encoder_cnt);
					}
					else if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= MANUAL_UNLOCK_CNT_DEVIATION_VALUE && (lock_mute!=2))
					{
						//手动开锁
						lock_mute = 2;
						lockMsg.lock = LOCK_ACTION_UNLOCK_MACH;		//机械开锁成功
						OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
						LOCKBIGPRO_LOG("manual unlock in place %d\r\n",encoder_data.encoder_cnt);
					}
				}
				else
				{
					if(abs(encoder_data.range_min - encoder_data.encoder_cnt) <= MANUAL_LOCK_CNT_DEVIATION_VALUE && (lock_mute!=1))
					{
						//手动上锁
						lock_mute = 1;
						lockMsg.lock = LOCK_ACTION_LOCKED_MACH;		//机械上锁成功
						OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
						LOCKBIGPRO_LOG("manual lock in place %d\r\n",encoder_data.encoder_cnt);
					}
					else if(abs(encoder_data.range_max - encoder_data.encoder_cnt) <= MANUAL_UNLOCK_CNT_DEVIATION_VALUE && (lock_mute!=2))
					{
						//手动开锁
						lock_mute = 2;
						lockMsg.lock = LOCK_ACTION_UNLOCK_MACH;		//机械开锁成功
						OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
						LOCKBIGPRO_LOG("manual unlock in place %d\r\n",encoder_data.encoder_cnt);
					}

				}

				break;

			default: 
				return;
		}

	}
}	




/**
  * @brief  锁体启动
  *         
  * @note   
  */
static void LockBigPro_Start(void)
{
	static uint8_t initFlag = 0;

    if (initFlag == 0)
    {
		initFlag = 1;

        OSAL_NvRead(0, &lock_config, sizeof(lock_config));

        if (lock_config.init_flag != 0xFA)
        {
			lock_config.range_sum = 0;
            lock_config.init_flag = 0; 		//首次上电
            lock_config.torque = LOCKED_TORQUE_SMALL;   //默认扭力：小
            lock_config.dir = LOCKED_DIR_LEFT;          //默认方向：左
            OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
			LOCKBIGPRO_LOG("lockbigpro motor no calibration\r\n");
        }
		else
		{
			encoder_data.range_sum = lock_config.range_sum;
			LOCKBIGPRO_LOG("lockbigpro motor has the calibration\r\n");
			LOCKBIGPRO_LOG("lockbigpro motor range sum %d,dir:%d\r\n",encoder_data.range_sum,lock_config.dir);
			MotorBigPro_SetDirection(lock_config.dir);	//设置电机方向
			Lock_Ctrl_Sub(LOCK_CTRL_LOCKED);

		}
		


        MotorBigPro_SetDirection(lock_config.dir);	//设置电机方向

		LOCKBIGPRO_LOG("lockbigpro start\r\n");
		/* 注册中断回调 */
        Device_RegisteredCB(IRQ_VHW_LOCKBIG_COUNTER, LockBig_Counter_Irq_Handler);
    }
}


//处理邮箱信息
static void LockBigPro_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
		case LOCK_MBOX_CTRL:		//操作上锁/开锁
		{
			uint8_t ctrl;
			ctrl = msg[1];
			Lock_Ctrl_Sub((LockCtrl_enum_t)ctrl);
		}
		break;

		case LOCK_MBOX_SET_DIR:		//设置电机方向
		{
			uint8_t dir;
			dir = msg[1];
			LockBigPro_SetDir_Sub((LockedDir_enum_t)dir);
		}
		break;

		case LOCK_MBOX_SET_TORQUE:	//设置电机扭力
		{
			uint8_t torque;
			torque = msg[1];
			LockBigPro_SetTorque_Sub((LockedTorque_enum_t)torque);
		}
		break;

		case LOCK_MBOX_TESTCTRL:	//产测接口
		{
			uint8_t testMode, dataLen, data[10];
			testMode = msg[1];
			dataLen = msg[2];
			memcpy(data, &msg[3], dataLen);
			Lock_TestCtrl_Sub((Lock_Test_Mode_enum_t)testMode, data, dataLen);
		}
		break;

		case LOCK_MBOX_SET_RANGE:	//校准电机
		{
			if (motorStatus.current == MOTOR_STA_IDLE)
    		{
				LOCKBIGPRO_LOG("LockBigPro start calibrate\r\n");
				motor_calibrate_flag = 1;
				lock_config.range_sum = 0;		//清空总行程
				lock_config.init_flag = 0; 		//
				if(msg[1] == LOCKED_DIR_LEFT)
				{
					lock_config.dir = LOCKED_DIR_LEFT;
				}
				else if(msg[1] == LOCKED_DIR_RIGHT)
				{
					lock_config.dir = LOCKED_DIR_RIGHT;
				}
				else
				{
					lock_config.dir = LOCKED_DIR_LEFT;
				}
				MotorBigPro_SetDirection(lock_config.dir);
				encoder_data.range_max = 0;
				encoder_data.range_min = 0;
				Lock_Ctrl_Sub(LOCK_CTRL_LOCKED);	//电机先上锁
			}	
		}
		break;

		case LOCK_MBOX_SET_RESET:	//锁复位
		{
			lock_config.range_sum = 0;
			lock_config.init_flag = 0; 		//首次上电
			lock_config.torque = LOCKED_TORQUE_SMALL;   //默认扭力：小
			lock_config.dir = LOCKED_DIR_LEFT;          //默认方向：左
			OSAL_NvWrite(0, &lock_config, sizeof(lock_config));

			LOCKBIGPRO_LOG("lockbigpro reset\r\n");
		}
		break;

		default:
			
			break;
    }
}


/**
  * @brief  锁体休眠
  *         
  * @note   
  */
static void LockBigPro_Sleep(void)
{
	MotorBigPro_Disable();
}



/**
  * @brief  锁体任务函数
  *
  * @note
  *         
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t LockBigPro_Task(uint32_t event)
{
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{
		LOCKBIGPRO_LOG("Lock BigPro task start\r\n");
		Device_Enable(vADC_1);
		Device_Enable(vCOUNTER_0);
        LockBigPro_Start();
		return ( event ^ EVENT_SYS_START );
	}
	
	if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[30] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            LockBigPro_ProcessMbox(buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }
	
	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        LOCKBIGPRO_LOG("Lock task sleep\r\n");
		Device_Disable(vADC_1);
        LockBigPro_Sleep();
		return ( event ^ EVENT_SYS_SLEEP );
	}
	
	/* 系统中断事件 */
	if (event & EVENT_SYS_ISR)
	{
		LockBigPro_CounterIsr();
		return ( event ^ EVENT_SYS_ISR );
	}

    /* 电机监控事件 */
    if (event & EVENT_MOTOR_MONITOR)
	{
		LockBigPro_MotorMonitor();
		//LOCKBIGPRO_LOG("motor_calibrate_flag= %d\r\n",motor_calibrate_flag);
        if ((motorStatus.current != MOTOR_STA_IDLE) || (motor_calibrate_flag == 1))//非空闲状态下不允许休眠
        {

            OSAL_SetTaskStatus(TASK_STA_ACTIVE);
        }
        else
        {
            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
		
        return ( event ^ EVENT_MOTOR_MONITOR );
    }
	return 0;
}
COMPONENT_TASK_EXPORT(COMP_LOCK, LockBigPro_Task, 6);


static int32_t LockBigPro_CounterWakeupHandle(uint32_t dev)
{

	return 1;
}

COMPONENT_WAKEUP_EXPORT(COMP_LOCK, LockBigPro_CounterWakeupHandle, vCOUNTER_0); 
